```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>一致性哈希算法解析 | 分布式系统关键技术</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.8;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .code-block {
            background: #282c34;
            color: #abb2bf;
            border-radius: 8px;
            overflow: hidden;
        }
        .code-header {
            background: #1e2227;
            padding: 0.5rem 1rem;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .code-body {
            padding: 1.25rem;
        }
        .feature-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .hash-node {
            transition: all 0.3s ease;
        }
        .hash-node:hover {
            transform: scale(1.05);
        }
        .highlight {
            position: relative;
        }
        .highlight:after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 30%;
            background-color: rgba(110, 142, 251, 0.2);
            z-index: -1;
            transition: all 0.3s ease;
        }
        .highlight:hover:after {
            height: 50%;
        }
        .mermaid {
            background: white;
            padding: 1.5rem;
            border-radius: 0.5rem;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 sm:px-6 lg:px-8">
        <div class="max-w-5xl mx-auto text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-6 leading-tight">一致性哈希算法解析</h1>
            <p class="text-xl md:text-2xl mb-8 max-w-3xl mx-auto opacity-90">分布式系统中的优雅数据分布方案</p>
            <div class="flex justify-center space-x-4">
                <a href="#concept" class="bg-white text-purple-600 hover:bg-gray-100 px-6 py-3 rounded-lg font-medium transition duration-300">
                    <i class="fas fa-lightbulb mr-2"></i>核心概念
                </a>
                <a href="#implementation" class="bg-transparent border-2 border-white hover:bg-white hover:text-purple-600 px-6 py-3 rounded-lg font-medium transition duration-300">
                    <i class="fas fa-code mr-2"></i>实现原理
                </a>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
        <!-- Introduction -->
        <section class="mb-16">
            <p class="text-lg text-gray-700 mb-6">
                设计和实现一致性哈希算法（Consistent Hashing）是一项在分布式系统中广泛使用的重要技术，尤其在分布式缓存、数据库分片和负载均衡中具有重要意义。为了解决数据分布的均匀性和扩展性问题，一致性哈希提供了一种有效的解决方案。
            </p>
            <div class="bg-blue-50 border-l-4 border-blue-500 p-4 mb-8">
                <div class="flex">
                    <div class="flex-shrink-0">
                        <i class="fas fa-info-circle text-blue-500 text-xl"></i>
                    </div>
                    <div class="ml-3">
                        <p class="text-sm text-blue-700">
                            一致性哈希算法最早由David Karger等人于1997年在论文《Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web》中提出。
                        </p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Background Section -->
        <section id="background" class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-purple-100 p-3 rounded-full mr-4">
                    <i class="fas fa-question-circle text-purple-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">背景与问题</h2>
            </div>
            <div class="prose max-w-none">
                <p class="text-gray-700 mb-4">
                    在分布式系统中，经常需要将数据分布到不同的节点上。例如，在分布式缓存中，我们可能希望将数据项均匀地分布到多个缓存服务器上。当增加或减少缓存服务器时，我们希望尽可能少地移动数据来保持系统的平衡。这就是一致性哈希算法的用武之地。
                </p>
                <p class="text-gray-700 mb-4">
                    传统的哈希算法（如取模运算 <code class="bg-gray-100 px-2 py-1 rounded">hash(key) % N</code>）在节点数量 <code class="bg-gray-100 px-2 py-1 rounded">N</code> 变化时，会导致大量的数据重新分布。例如，当节点数从 <code class="bg-gray-100 px-2 py-1 rounded">N</code> 增加到 <code class="bg-gray-100 px-2 py-1 rounded">N+1</code> 时，几乎所有的数据项都需要重新计算其位置，这会造成很大的开销。为了解决这个问题，一致性哈希应运而生。
                </p>
            </div>

            <div class="mt-8 grid md:grid-cols-2 gap-6">
                <div class="bg-white p-6 rounded-xl shadow-md border border-gray-100">
                    <div class="flex items-center mb-4">
                        <div class="bg-red-100 p-2 rounded-full mr-3">
                            <i class="fas fa-times text-red-500"></i>
                        </div>
                        <h3 class="text-xl font-semibold text-gray-800">传统哈希的问题</h3>
                    </div>
                    <ul class="space-y-2 text-gray-700">
                        <li class="flex items-start">
                            <i class="fas fa-chevron-right text-xs text-purple-500 mt-1 mr-2"></i>
                            节点变化时数据大规模迁移
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-chevron-right text-xs text-purple-500 mt-1 mr-2"></i>
                            无法实现优雅的水平扩展
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-chevron-right text-xs text-purple-500 mt-1 mr-2"></i>
                            节点负载不均衡问题
                        </li>
                    </ul>
                </div>
                <div class="bg-white p-6 rounded-xl shadow-md border border-gray-100">
                    <div class="flex items-center mb-4">
                        <div class="bg-green-100 p-2 rounded-full mr-3">
                            <i class="fas fa-check text-green-500"></i>
                        </div>
                        <h3 class="text-xl font-semibold text-gray-800">一致性哈希优势</h3>
                    </div>
                    <ul class="space-y-2 text-gray-700">
                        <li class="flex items-start">
                            <i class="fas fa-chevron-right text-xs text-purple-500 mt-1 mr-2"></i>
                            节点变更时最小化数据迁移
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-chevron-right text-xs text-purple-500 mt-1 mr-2"></i>
                            支持动态扩展和收缩
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-chevron-right text-xs text-purple-500 mt-1 mr-2"></i>
                            通过虚拟节点实现负载均衡
                        </li>
                    </ul>
                </div>
            </div>
        </section>

        <!-- Concept Section -->
        <section id="concept" class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-blue-100 p-3 rounded-full mr-4">
                    <i class="fas fa-atom text-blue-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">一致性哈希算法的基本原理</h2>
            </div>
            
            <p class="text-gray-700 mb-6">
                一致性哈希算法将所有可能的哈希值组织成一个逻辑环（哈希环），环的范围从 0 到 2<sup>32</sup> - 1（或一个大的数字）。所有的节点和数据项都会被哈希到这个环上。算法的核心思想是：将每个数据项放到顺时针方向最近的节点上。
            </p>

            <div class="grid md:grid-cols-2 gap-8 mb-8">
                <div>
                    <h3 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center">
                        <span class="w-8 h-8 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center mr-3">1</span>
                        哈希环构造
                    </h3>
                    <div class="prose max-w-none">
                        <p class="text-gray-700 mb-4">
                            一致性哈希算法通过将哈希值空间视为一个逻辑环来实现。我们可以想象环上有很多位置，每个位置代表一个哈希值。环的起点是 0，终点是 2<sup>32</sup> - 1。
                        </p>
                        <p class="text-gray-700">
                            每个物理节点（例如缓存服务器）通过哈希函数 <code class="bg-gray-100 px-2 py-1 rounded">hash(node)</code> 映射到环上的某个位置。例如，节点 A 可能映射到位置 1000，节点 B 映射到位置 5000。
                        </p>
                    </div>
                </div>
                <div>
                    <h3 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center">
                        <span class="w-8 h-8 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center mr-3">2</span>
                        数据存储策略
                    </h3>
                    <div class="prose max-w-none">
                        <p class="text-gray-700 mb-4">
                            当需要存储一个数据项时，首先计算该数据项的哈希值 <code class="bg-gray-100 px-2 py-1 rounded">hash(data)</code>，然后顺时针查找最近的节点。这个节点就是存储该数据项的目标节点。
                        </p>
                        <p class="text-gray-700">
                            这种设计使得节点增加或减少时，只有附近的数据需要重新分配，而不是整个数据集。
                        </p>
                    </div>
                </div>
            </div>

            <!-- Visualization -->
            <div class="bg-white p-6 rounded-xl shadow-md border border-gray-100 mb-8">
                <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
                    <i class="fas fa-project-diagram text-purple-500 mr-2"></i>
                    哈希环可视化
                </h3>
                <div class="mermaid">
                    graph LR
                        A[哈希环 0-2^32-1] --> B[节点A]
                        A --> C[节点B]
                        A --> D[节点C]
                        A --> E[数据项1 --> 节点B]
                        A --> F[数据项2 --> 节点C]
                        A --> G[数据项3 --> 节点A]
                </div>
            </div>

            <!-- Virtual Nodes -->
            <div class="bg-white p-6 rounded-xl shadow-md border border-gray-100">
                <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
                    <span class="w-8 h-8 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center mr-3">3</span>
                    虚拟节点技术
                </h3>
                <div class="prose max-w-none">
                    <p class="text-gray-700 mb-4">
                        为了进一步改善数据分布的均匀性，一致性哈希通常使用<strong class="highlight">虚拟节点</strong>。每个物理节点对应多个虚拟节点，每个虚拟节点都有独立的哈希值。这种做法可以减少因为节点数量变化而引起的数据迁移，同时平衡节点之间的负载。
                    </p>
                    <ul class="space-y-2 text-gray-700 mb-4">
                        <li class="flex items-start">
                            <i class="fas fa-chevron-right text-xs text-purple-500 mt-1 mr-2"></i>
                            <strong>虚拟节点的创建：</strong>一个物理节点会被映射为多个虚拟节点（通常通过在节点名称后加上编号并进行哈希计算）。
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-chevron-right text-xs text-purple-500 mt-1 mr-2"></i>
                            <strong>提高数据分布均匀性：</strong>通过虚拟节点的使用，可以使数据更均匀地分布在物理节点上，从而避免因为节点分布不均匀造成的数据倾斜问题。
                        </li>
                    </ul>
                </div>
                
                <div class="mermaid">
                    graph TD
                        subgraph 物理节点
                        A[节点A]
                        B[节点B]
                        end
                        subgraph 虚拟节点
                        A1[节点A#1]
                        A2[节点A#2]
                        A3[节点A#3]
                        B1[节点B#1]
                        B2[节点B#2]
                        B3[节点B#3]
                        end
                        A --> A1
                        A --> A2
                        A --> A3
                        B --> B1
                        B --> B2
                        B --> B3
                </div>
            </div>
        </section>

        <!-- Advantages Section -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-green-100 p-3 rounded-full mr-4">
                    <i class="fas fa-star text-green-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">一致性哈希的优势</h2>
            </div>
            
            <div class="grid md:grid-cols-3 gap-6">
                <div class="feature-card bg-white p-6 rounded-xl shadow-md border border-gray-100 transition duration-300">
                    <div class="text-purple-500 text-3xl mb-4">
                        <i class="fas fa-exchange-alt"></i>
                    </div>
                    <h3 class="text-xl font-semibold text-gray-800 mb-3">最小化数据迁移</h3>
                    <p class="text-gray-700">
                        当节点增加或减少时，一致性哈希只需要重新分配很少一部分的数据。例如，当一个新节点加入时，它只会从环上顺时针方向的第一个节点处获取一部分数据，而不影响其他节点。
                    </p>
                </div>
                
                <div class="feature-card bg-white p-6 rounded-xl shadow-md border border-gray-100 transition duration-300">
                    <div class="text-purple-500 text-3xl mb-4">
                        <i class="fas fa-expand"></i>
                    </div>
                    <h3 class="text-xl font-semibold text-gray-800 mb-3">支持动态扩展</h3>
                    <p class="text-gray-700">
                        一致性哈希天然支持节点的动态扩展和收缩，适合分布式系统的弹性需求。系统可以随着负载变化灵活调整节点数量，而不会导致大量数据迁移。
                    </p>
                </div>
                
                <div class="feature-card bg-white p-6 rounded-xl shadow-md border border-gray-100 transition duration-300">
                    <div class="text-purple-500 text-3xl mb-4">
                        <i class="fas fa-balance-scale"></i>
                    </div>
                    <h3 class="text-xl font-semibold text-gray-800 mb-3">负载均衡</h3>
                    <p class="text-gray-700">
                        通过使用虚拟节点，一致性哈希可以较好地实现负载均衡，使每个物理节点承担近似的请求和数据量。这避免了热点问题，提高了系统整体性能。
                    </p>
                </div>
            </div>
        </section>

        <!-- Implementation Section -->
        <section id="implementation" class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-orange-100 p-3 rounded-full mr-4">
                    <i class="fas fa-code text-orange-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">一致性哈希算法的实现步骤</h2>
            </div>
            
            <div class="prose max-w-none mb-8">
                <ol class="space-y-6 text-gray-700">
                    <li class="flex items-start">
                        <span class="flex-shrink-0 w-8 h-8 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center mr-4">1</span>
                        <div>
                            <strong>计算节点和数据的哈希值：</strong>通过一个合适的哈希函数（例如 MD5 或 SHA-256），计算节点和数据项的哈希值，并将其映射到哈希环上。
                        </div>
                    </li>
                    <li class="flex items-start">
                        <span class="flex-shrink-0 w-8 h-8 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center mr-4">2</span>
                        <div>
                            <strong>存储节点：</strong>将所有节点（或虚拟节点）的哈希值存储在一个有序的数据结构中（如 <code class="bg-gray-100 px-2 py-1 rounded">TreeMap</code>），便于快速查找。
                        </div>
                    </li>
                    <li class="flex items-start">
                        <span class="flex-shrink-0 w-8 h-8 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center mr-4">3</span>
                        <div>
                            <strong>数据查找与存储：</strong>计算每个数据项的哈希值，然后在哈希环上顺时针查找最近的节点。这个查找过程可以通过 <code class="bg-gray-100 px-2 py-1 rounded">TreeMap</code> 的 <code class="bg-gray-100 px-2 py-1 rounded">ceilingEntry()</code> 方法快速实现。
                        </div>
                    </li>
                    <li class="flex items-start">
                        <span class="flex-shrink-0 w-8 h-8 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center mr-4">4</span>
                        <div>
                            <strong>处理节点的增加和删除：</strong>当有节点增加或删除时，重新计算受影响数据项的目标节点，并进行数据迁移。
                        </div>
                    </li>
                </ol>
            </div>

            <!-- Code Example -->
            <div class="mb-8">
                <h3 class="text-2xl font-semibold text-gray-800 mb-4 flex items-center">
                    <i class="fas fa-laptop-code text-purple-500 mr-2"></i>
                    示例代码实现
                </h3>
                <div class="code-block mb-6">
                    <div class="code-header">
                        <div class="text-gray-400 text-sm">ConsistentHashingDemo.java</div>
                        <div class="flex space-x-2">
                            <div class="w-3 h-3 rounded-full bg-red-500"></div>
                            <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
                            <div class="w-3 h-3 rounded-full bg-green-500"></div>
                        </div>
                    </div>
                    <div class="code-body">
                        <pre class="text-sm overflow-x-auto"><code>import java.util.SortedMap;
import java.util.TreeMap;

public class ConsistentHashingDemo {
    private final SortedMap&lt;Integer, String&gt; circle = new TreeMap&lt;&gt;();
    private final int virtualNodes;

    public ConsistentHashingDemo(int virtualNodes) {
        this.virtualNodes = virtualNodes;
    }

    private int hash(String key) {
        return key.hashCode() & 0xfffffff; // 生成哈希值
    }

    public void addNode(String node) {
        for (int i = 0; i &lt; virtualNodes; i++) {
            int hash = hash(node + "#" + i);
            circle.put(hash, node);
        }
    }

    public void removeNode(String node) {
        for (int i = 0; i &lt; virtualNodes; i++) {
            int hash = hash(node + "#" + i);
            circle.remove(hash);
        }
    }

    public String getNode(String key) {
        if (circle.isEmpty()) {
            return null;
        }
        int hash = hash(key);
        if (!circle.containsKey(hash)) {
            SortedMap&lt;Integer, String&gt; tailMap = circle.tailMap(hash);
            hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
        }
        return circle.get(hash);
    }

    public static void main(String[] args) {
        ConsistentHashingDemo hash = new ConsistentHashingDemo(3);
        hash.addNode("NodeA");
        hash.addNode("NodeB");
        hash.addNode("NodeC");

        System.out.println("Key1 is stored in: " + hash.getNode("Key1"));
        System.out.println("Key2 is stored in: " + hash.getNode("Key2"));

        hash.removeNode("NodeB");
        System.out.println("After removing NodeB, Key1 is stored in: " + hash.getNode("Key1"));
    }
}</code></pre>
                    </div>
                </div>
            </div>
        </section>

        <!-- Application Section -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-indigo-100 p-3 rounded-full mr-4">
                    <i class="fas fa-cogs text-indigo-600 text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">实际应用场景</h2>
            </div>
            
            <div class="bg-white p-6 rounded-xl shadow-md border border-gray-100">
                <div class="grid md:grid-cols-3 gap-6">
                    <div class="hash-node bg-gray-50 p-5 rounded-lg border border-gray-200">
                        <div class="text-purple-500 text-2xl mb-3">
                            <i class="fas fa-database"></i>
                        </div>
                        <h3 class="text-lg font-semibold text-gray-800 mb-2">分布式缓存</h3>
                        <p class="text-gray-700 text-sm">
                            Memcached、Redis等分布式缓存系统使用一致性哈希来分布数据，当增加或减少缓存节点时，最小化数据迁移。
                        </p>
                    </div>
                    
                    <div class="hash-node bg-gray-50 p-5 rounded-lg border border-gray-200">
                        <div class="text-purple-500 text-2xl mb-3">
                            <i class="fas fa-server"></i>
                        </div>
                        <h3 class="text-lg font-semibold text-gray-800 mb-2">数据库分片</h3>
                        <p class="text-gray-700 text-sm">
                            MongoDB、Cassandra等分布式数据库使用一致性哈希进行数据分片，实现数据的水平扩展。
                        </p>
                    </div>
                    
                    <div class="hash-node bg-gray-50 p-5 rounded-lg border border-gray-200">
                        <div class="text-purple-500 text-2xl mb-3">
                            <i class="fas fa-network-wired"></i>
                        </div>
                        <h3 class="text-lg font-semibold text-gray-800 mb-2">负载均衡</h3>
                        <p class="text-gray-700 text-sm">
                            Nginx、HAProxy等负载均衡器使用一致性哈希算法将请求路由到后端服务器，保持会话一致性。
                        </p>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-8">
        <div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-4 md:mb-0">
                    <h3 class="text-xl font-semibold text-white mb-1">技术小馆</h3>
                    <p class="text-gray-400">探索分布式系统核心技术</p>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="text-gray-300 hover:text-white transition duration-300">
                        <i class="fas fa-external-link-alt mr-2"></i>http://www.yuque.com/jtostring
                    </a>
                </div>
            </div>
            <div class="border-t border-gray-800 mt-6 pt-6 text-center text-sm text-gray-500">
                &copy; 2023 技术小馆. 保留所有权利.
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```